package es.uned.etsii.si3.taller.servlets;

import java.sql.SQLException;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

import es.uned.etsii.si3.taller.Cliente;
import es.uned.etsii.si3.taller.FactoriaDAO;
import es.uned.etsii.si3.taller.FactoriaFunciones;
import es.uned.etsii.si3.taller.Provincia;
import es.uned.etsii.si3.taller.Usuario;
import es.uned.etsii.si3.taller.misc.ProporcionaFuncionalidad;

public class AltaYModificacionClientes
	extends ActionSupport
	implements Preparable
{
	private static final long serialVersionUID = 1L;
	
	private Usuario usuario;
	private Cliente cliente;
	private List<Provincia> listaProvincias;
	private int provinciaParaCliente = 0;
	private boolean listoParaAceptar = false;
	private boolean esClienteNuevo = true;

	// Getters y setters para los atributos de los formularios
	public Usuario getUsuario() {
		return usuario;
	}
	
	public void setUsuario(Usuario usuarioWeb) {
		usuario = usuarioWeb;
	}
	
	public Cliente getCliente() {
		return cliente;
	}
	
	public void setCliente(Cliente clienteWeb) {
		cliente = clienteWeb;
	}
	
	public List<Provincia> getListaProvincias() {
		return listaProvincias;
	}
	
	public void setListaProvincias(List<Provincia> lista) {
		listaProvincias = lista;
	}
	
	public int getProvinciaParaCliente() {
		return provinciaParaCliente;
	}
	
	public void setProvinciaParaCliente(int prov) {
		provinciaParaCliente = prov;
	}
	
	public boolean getListoParaAceptar() {
		return listoParaAceptar;
	}
	
	public boolean getEsClienteNuevo() {
		return esClienteNuevo;
	}
	
	public void setEsClienteNuevo(boolean nuevo) {
		esClienteNuevo = nuevo;
	}

	/**
	 * Prepara datos necesarios para el formulario
	 */
	@Override
	public void prepare() throws Exception {
		setListaProvincias(Provincia.hacerListaProvincias());
		
		setEsClienteNuevo(clientePorUsuario() == null);
	}
	
	Cliente clientePorUsuario() throws SQLException {
		if (usuario != null) {
			return Usuario.buscarPorNombreUsuario(usuario.getUsuario()).getCliente();
		}

		return null;
	}
	
	public String display() {
		return NONE;
	}
	
	private boolean nuloOVacio(String obj) {
		return (obj == null) || (obj.trim().isEmpty());
	}
	
	/**
	 * A partir de los datos introducidos modifica o crea el usuario
	 */
	public void validate() {
		// TODO: Validar los campos para asegurar que no se pasan de tamaño (o pasarlo al formulario)
		if (cliente != null) {
			if ((usuario == null) || nuloOVacio(usuario.getUsuario())) {
				addFieldError("usuario.usuario", "Debe especificar un usuario para el cliente");
			}
			else {
				try {
					Usuario tempUsuario = Usuario.buscarPorNombreUsuario(usuario.getUsuario());
					if (tempUsuario == null) {
						addFieldError("usuario.usuario", "Error: el usuario no existe");
					}
					else {
						if (((tempUsuario.getCliente() == null) && (tempUsuario.getEmpleado() == null)) || (!esClienteNuevo)) {
							setUsuario(tempUsuario);
						}
						else {
							addFieldError("usuario.usuario", "Usuario ilegal: ya está asociado a otro cliente/empleado");
						}
					}
				} catch (SQLException e) {
					addFieldError("usuario.usuario", "Error SQL al intentar comprobar el usuario");
				}
			}

			// TODO: ¿Comprobar que el DNI del cliente es correcto? 
			if (nuloOVacio(cliente.getDni())) {
				cliente.setDni("");
				addFieldError("cliente.dni", "El DNI no puede estar en blanco");
			}

			if (nuloOVacio(cliente.getNombre())) {
				cliente.setNombre("");
				addFieldError("cliente.nombre", "El nombre no puede estar en blanco");
			}
			// No se fuerzan los apellidos (eg. el cliente es una empresa)
			if (nuloOVacio(cliente.getApellidos())) {
				cliente.setApellidos("");
			}			
			if (nuloOVacio(cliente.getTelefono())) {
				cliente.setTelefono("");
				addFieldError("cliente.telefono", "El teléfono no puede estar en blanco");				
			}
			
			if ((cliente.getCodigoPostal() != 0) &&
				((cliente.getCodigoPostal() < 1000) || (cliente.getCodigoPostal() > 52999)))
			{
				addFieldError("cliente.codigoPostal", "C.P. fuera de rango");
			}
			
			if (nuloOVacio(cliente.getDireccion())) {
				cliente.setDireccion("");
			}
			
			if (nuloOVacio(cliente.getPoblacion())) {
				cliente.setPoblacion("");
			}
			
			try {
				cliente.setProvincia(FactoriaDAO.recuperar(Provincia.class, provinciaParaCliente));
			} catch (SQLException e) {
				addFieldError("provinciaParaCliente", "Error SQL al intentar recuperar la provincia");
			}
		}
	}
	
	public String confirmar() {
		addActionMessage("Compruebe los datos una segunda vez antes de confirmar");
		listoParaAceptar = true;
		return NONE;
	}

	/**
	 * Crea el cliente
	 * @return actionerror
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.ADMIN_NUEVO_CLIENTE)
	public String crear() {
		try {
			getCliente().setUsuario(usuario);
			Cliente.crear(getCliente());
			addActionMessage("El cliente " + cliente.toString() + " ha sido creado correctamente");
		} catch (SQLException e) {
			addActionError("Al intentar guardar los datos del cliente: " + e.toString());
			return ERROR;
		}
		
		return SUCCESS;
	}

	/**
	 * Modifica el cliente
	 * @return actionerror
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.ADMIN_MODIFICAR_CLIENTE)
	public String actualizar() {
		try {
			Cliente previo = usuario.getCliente();

			if (previo == null) {
				addActionError("No se ha podido recuperar el cliente para el usuario " + usuario.getUsuario());
				return ERROR;
			}
			
			previo.actualizar(cliente);
			addActionMessage("El cliente " + previo.toString() + " ha sido modificado con éxito");
		} catch (SQLException e) {
			addActionError("Al intentar guardar los datos del cliente: " + e.toString());
			return ERROR;
		}
		
		return SUCCESS;
	}
}